package com.erp.app.common.VUtil.sql;

import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Map;

public class TableStructureDumper {
    Connection conn;
    boolean isOracle = false;
    String dbName;
    ITableStructureDumper dumper;
    boolean bShowRealPK = false;

    public TableStructureDumper(Connection conn) throws SQLException {
        this.conn = conn;
        DatabaseMetaData dbmd = conn.getMetaData();
        dbName = dbmd.getDatabaseProductName();
        if ("Oracle".equals(dbName))
            dumper = new OracleTableStructureDumper(conn);
        else if ("Microsoft SQL Server".equals(dbName))
            dumper = new MSSQLTableStructureDumper(conn);
        else
            dumper = new ATableStructureDumper(conn);
    }

    public void setShowRealPK(boolean b) {
        bShowRealPK = b;
    }

    public void finalize() {
        conn = null;
    }

    public String dump(ResultSetMetaData md, String sTable) throws SQLException {
        StringBuffer sb = new StringBuffer();

        sb.append("CREATE TABLE " + sTable + " (\r\n");
        sb.append(dumper.getColumns(md, sTable));
        sb.append(dumpTableKeys(sTable) + "\r\n");
        sb.append(");\r\n");
        return sb.toString();
    }

    public String dumpTableKeys(String sTable) throws SQLException {
        ResultSet rs = null;
        try {
            StringBuffer sb = new StringBuffer();

            Map m = dumper.getPrimaryKeys(sTable);
            if (bShowRealPK) {
                m.put(ITableStructureDumper.SHOW_PK_NAME, m.get(ITableStructureDumper.PK_NAME));
            }
            // Subtract the key for SHOW_PK_NAME and PK_NAME.
            if (m.size() - 2 > 0) {
                sb.append(",\r\n    " + dumper.getConstraintLine(m) + " (\r\n        ");
                sb.append(m.get(new Integer(1)));
                for (int i = 1; i < m.size() - 2; i++) {
                    sb.append("," + m.get(new Integer(i + 1)));
                }
                sb.append("\r\n    )");
            }
            return sb.toString();
        } catch (SQLException x) {
            throw x;
        } finally {
            if (null != rs)
                rs.close();
        }
    }

    public String getTableStructure(String sTable) throws SQLException {
        Statement stmt = conn.createStatement();
        ResultSet rs = null;
        try {
            sTable = sTable.trim();
            rs = stmt.executeQuery("select * from " + sTable + " where 1 <> 1");
            String s = dump(rs.getMetaData(), sTable);
            rs.close();
            return s;
        } catch (SQLException x) {
            throw x;
        } finally {
            if (null != stmt) {
                try {
                    stmt.close();
                } catch (SQLException x) {
                    x.printStackTrace();
                }
            }
            if (null != rs)
                rs.close();
        }
    }

    public String getTablesStructure(Object[] sTables) throws SQLException {
        StringBuffer sb = new StringBuffer();

        for (int i = 0; i < sTables.length; i++)
            sb.append(getTableStructure((String) sTables[i]) + "\n");
        return sb.toString();
    }
}
